package mc

import (
	"gitee.com/benben-mao/djson"
	"github.com/gin-gonic/gin"
	"net/url"
)

//  调函数定义
type (
	ContextBeforeFunc func(c *gin.Context) (err error) //  初始化上下文前回调
	ContextAfterFunc  func(ctx *Context) (err error)   // 初始化上下文后回调
	GetRowAuthModelsFunc func() []string // 获取所有具有行权限模型回调
	GetRowAuthFunc     func(ctx *Context, modelName string) (authCodes []string, isAll bool)              // 获取行权限回调
	GetColAuthFunc     func(ctx *Context, modelName string) (authCodes []string, isAll bool)              // 获取列权限回调
	GetModelConfigFunc func(ctx *Context, modelName string, option map[string]string) (content interface{}, scripts []djson.Script) // 获取模型配置内容回调
	RequestLogWriteFunc func (c *gin.Context, value url.Values) map[string][]string //写日志回调
)

// 权限选项
type authOption struct {
	GetRowAuthModelsCallback GetRowAuthModelsFunc
	GetRowAuthCallback GetRowAuthFunc
	GetColAuthCallback GetColAuthFunc
}

// 响应选项
type responseOption struct {
	CodeName         string     // 代码项的key，默认值 code
	MessageName      string     // 消息项的key, 默认值 msg
	DataName         string     // 数据项的key, 默认值 data
	TotalName        string     // 总记录数或影响的记录数项的key，默认值 total
	FootName         string     // 表尾汇总数据项的key，默认值 foot
	SuccessCodeValue string     // 成功代码值，默认值 0000
	FailCodeValue    string     // 失败默认代码值，默认值 1000
	AjaxRenderType   RenderType // 默认ajax渲染类型 RenderTypeJSON
	ErrorTemplate    string     // 错误页面模版，默认值 "error.html"
	MessageTemplate  string     // 消息页面棋牌，默认值message.html
}

// 请求选项
type requestOption struct {
	OrderName             string              // 排序字段，默认值 order
	PageName              string              // 前端页码参数名，默认值："page"
	PageSizeName          string              // 前端页记录数参数名，默认值："limit"
	PageSizeValue         int                 // 默认页记录数，默认值：50
	ContextBeforeCallback ContextBeforeFunc   // 初始化上下文前回调
	ContextAfterCallback  ContextAfterFunc    // 初始化上下文后回调
	LogWriteCallback      RequestLogWriteFunc // //写日志回调
}

// 路由选项
type routerOption struct {
	UrlPathSep               string                            // URL路径之间的分割符号（不能使用_下线线），默认为 "/"
	UrlHtmlSuffix            string                            // URL伪静态后缀设置，默认为 "html"
	ControllerMap            map[string]map[string]IController // 控制器map
	BaseModuleName           string                            // 全局基础模块key，默认值 "base"
	BaseControllerName       string                            // 全局基础控制器key，默认值 "base"
	ModuleBaseControllerName string                            // 当前模块下基础控制器key，默认为 "base"
}

// 日志选项
type LogOption struct {
	Name     string `json:"name" yaml:"name"`         // 日志名称
	FileName string `json:"fileName" yaml:"fileName"` //日志文件路径及文件名
	Format   string `json:"format" yaml:"format"`     // 日志格式 ( text | json )
}

// mc选项结构体
type opt struct {
	engine                 *gin.Engine                  //
	Debug                  bool                         //调试模式
	DefaultConnName        string                       // 默认数据库连接名 默认值："default"
	DefaultLogName         string                       // 默认日志名 默认值 "default"
	Router                 routerOption                 // 路由选项
	Response               responseOption               // 结果项设置
	Request                requestOption                // 请求项设置
	ModelAuth              authOption                   // 权限项设置
	GetModelConfigCallback GetModelConfigFunc           // 获取模型配置内容回调
	TimeFormats            map[string]string            // 日期格式化
	CommonEnums            map[string][][]string // 公共枚举
	Logs                   []LogOption                  // 日志选项列表
}

// 默认选项设置
var option = opt{
	Debug:           false,
	DefaultConnName: "default",
	DefaultLogName:  "default",
	ModelAuth: authOption{
		// GetRowAuthModelsCallback: func() []string { return make([]string, 0) },
		GetRowAuthCallback: func(ctx *Context, modelName string) (authCodes []string, isAll bool) { return make([]string, 0), true },
		GetColAuthCallback: func(ctx *Context, modelName string) (authCodes []string, isAll bool) { return make([]string, 0), true },
		GetRowAuthModelsCallback: func() []string {return make([]string, 0)},
	},
	Router: routerOption{
		UrlPathSep:               "/",
		UrlHtmlSuffix:            "html",
		ControllerMap:            map[string]map[string]IController{},
		BaseModuleName:           "base",
		BaseControllerName:       "base",
		ModuleBaseControllerName: "base",
	},
	Response: responseOption{
		SuccessCodeValue: "0000",
		FailCodeValue:    "1000",
		CodeName:         "code",
		MessageName:      "msg",
		DataName:         "data",
		TotalName:        "total",
		FootName:         "foot",
		AjaxRenderType:   RenderTypeJSON,
		ErrorTemplate:    "error.html",
		MessageTemplate:  "message.html",
	},
	Request: requestOption{
		PageName:              "page",
		PageSizeName:          "limit",
		PageSizeValue:         50,
		OrderName:             "order",
		ContextBeforeCallback: func(c *gin.Context) (err error) { return },
		ContextAfterCallback:  func(ctx *Context) (err error) { return },
		LogWriteCallback: func(c *gin.Context, values url.Values) map[string][]string { return values},
	},
	GetModelConfigCallback: func(ctx *Context, modelName string, option map[string]string) (content interface{}, scripts []djson.Script) {
		return
	},
	TimeFormats: map[string]string{
		"datetime": "2006-01-02 15:04:05",
		"date":     "2006-01-02",
		"yearmonth": "2006-01",
		"time":     "15:04:05",
		"year":     "2006",
		"month":    "01",
		"day":      "02",
		"hour":     "15",
		"minute":   "04",
		"seconds":  "05",
	},
	CommonEnums: make(map[string][][]string),
}
